using Autofac;
using Autofac.Extensions.DependencyInjection;
using Essensoft.Paylink.Alipay;
using Essensoft.Paylink.WeChatPay;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi.Models;
using NLog.Web;
using StudyCompanion.Commons.Config;
using StudyCompanion.Commons.Converter;
using StudyCompanion.Commons.Filters;
using StudyCompanion.Core.Extensions;
using StudyCompanion.WebApi;
using System.Reflection;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using StudyCompanion.Commons.Helper;
using StudyCompanion.Core.Redis;

var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile("Config/appsettings.json", optional: false, reloadOnChange: true);

builder.Host
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureContainer<ContainerBuilder>(builder =>
    {
        builder.RegisterModule(new AutofacModuleRegister());
    })
    .ConfigureLogging(builder =>
    {
        builder.ClearProviders();
        builder.AddConsole();
        builder.AddNLog("Config/nlog.config");
    });

builder.Services.AddSingleton(new AppSettings(builder.Configuration));

#region 控制器
builder.Services.AddControllers(options =>
{
    options.Filters.Add(typeof(GlobalValidationAttribute));
    options.Filters.Add(typeof(GlobalExceptionsFilter));
})
    .AddJsonOptions(options =>
    {
        //该值指示是否允许、不允许或跳过注释。
        options.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip;
        //反序列话时是否区分大小写，默认为false
        options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
        //设置时间格式
        options.JsonSerializerOptions.Converters.Add(new DateTimeJsonConverter());
        options.JsonSerializerOptions.Converters.Add(new DateTimeNullableJsonConverter());
        //设置bool获取格式
        options.JsonSerializerOptions.Converters.Add(new BooleanJsonConverter());
        //设置Decimal获取格式
        options.JsonSerializerOptions.Converters.Add(new DecimalJsonConverter());
        //匿名类型
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        options.JsonSerializerOptions.Converters.Add(new IntJsonConverter());
        options.JsonSerializerOptions.Converters.Add(new LongJsonConverter());
        options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
    });
builder.Services.AddFluentValidationAutoValidation();
builder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);  //关闭aps.netcore自带的模型验证
builder.Services.AddCache();
builder.Services.AddJWTAuthorization();
builder.Services.AddSqlSugar(builder.Configuration.GetSection("Db").Get<SqlSugar.IOC.IocConfig>());
//Redis
// builder.Services.AddRedisServices(builder.Configuration.GetSection("Redis").Get<RedisConfig>());
StartupHelp.InitRedis(builder.Configuration.GetSection("Redis").Get<RedisConfig>().ConnectionString);
builder.Services.AddWeChatPay();                                                                        //微信支付
builder.Services.Configure<WeChatPayOptions>(builder.Configuration.GetSection("WeChatPay"));
builder.Services.AddAlipay();                                                                           //支付宝支付
builder.Services.Configure<AlipayOptions>(builder.Configuration.GetSection("WeChatPay"));
builder.Services.Configure<NoticeOptions>(builder.Configuration.GetSection("Notice"));                  //回调地址配置
builder.Services.AddSignalR();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHttpContextAccessor();
#endregion


builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(Assembly.Load("StudyCompanion.Services")));

//Swagger
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "小程序接口", Version = "v1" });
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Bearer",
        BearerFormat = "JWT",
        In = ParameterLocation.Header,
        Description = "JWT Authorization header using the Bearer scheme."
    });
    //设置全局认证
    c.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference
                                {
                                    Type = ReferenceType.SecurityScheme,
                                    Id = "Bearer"
                                }
                            },
                            Array.Empty<string>()
                        }
                    });
    c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "StudyCompanion.WebApi.xml"));
    c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "StudyCompanion.Dto.xml"));
    c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "StudyCompanion.Entity.xml"));
    c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "StudyCompanion.Model.xml"));
});

builder.Services.AddCors(options =>
{
    var _corsHosts = builder.Configuration.GetValue("Cors", string.Empty).Split(",", StringSplitOptions.RemoveEmptyEntries);
    options.AddPolicy("default", policy =>
    {
        policy.WithOrigins(_corsHosts)
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials();
    });
});

var app = builder.Build();

app.UseCors("default");

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger(c =>
    {
        c.RouteTemplate = $"/api/swagger/{{documentName}}/swagger.json";
        c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
        {
            swaggerDoc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"/", Description = "小程序接口" } };
        });
    });

    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint($"/api/swagger/v1/swagger.json", $"WebApi-v1");
        c.RoutePrefix = "api";
    });
}

app.UseHttpsRedirection();

app.UseAuthentication();


app.UseAuthorization();

app.MapControllers().RequireAuthorization();

app.MapHub<MessageHub>("/msg");

app.Run();